﻿using System.Linq;
using NUnit.Framework;
using NUnit.Framework.SyntaxHelpers;
using QuickTest.Core.Compilation;
using QuickTest.Core.TestRunner;
using QuickTest.Services.Packaging;
using QuickTest.Services.TextRetrieval;
using Rhino.Mocks;

namespace QuickTest.Tests.Services.Packaging
{
    [TestFixture]
    public class TestPackageServiceTests
    {
        private const string EmbeddedResourceTestSolutionPath = "QuickTest.Tests,QuickTest.Tests.Services.Packaging.Artifacts.TestSolution.sln";
        private const string EmbeddedResourceTestProjectPath = "QuickTest.Tests, QuickTest.Tests.Services.Packaging.Artifacts.TestProject.csproj";
        private const string EmbeddedResourceTestClassPath = "QuickTest.Tests, QuickTest.Tests.Services.Packaging.Artifacts.TestClass.cs";

        public const string TestProjectFilePath = TestUtils.TestDirectory + "/TestProject.csproj";
        public const string CompilationClassFilePath = TestUtils.TestDirectory + "/TestClass.cs";
        private const string OutputDirectory = TestUtils.TestDirectory + "/bin/debug/";
        private const string OutputAssemblyName = "TestProject.Tests.dll";

        private const string solutionName = "TestSolution";
        private const string solutionFile = TestUtils.TestDirectory + "/TestSolution.sln";

        [SetUp]
        public void SetUp()
        {
            TestUtils.CreateTestFile(EmbeddedResourceTestProjectPath, TestProjectFilePath);
            TestUtils.CreateTestFile(EmbeddedResourceTestClassPath, CompilationClassFilePath);
        }

        [TearDown]
        public void TearDown()
        {
            TestUtils.DeleteTestFiles();
        }

        [Test]
        public void CreateTestPackage_returns_test_package_containing_path_to_all_assemblies_in_output_directory()
        {
            var compiler = new MSBuildCompiler();

            var testPackageService = new TestPackageService(GetTextRetriever(), compiler, new DirectoryUri(OutputDirectory));

            ITestPackage testPackage = testPackageService.CreateTestPackage(solutionFile);

            Assert.That(testPackage.Assemblies.Any(f => f.EndsWith(OutputAssemblyName)), Is.True);
        }

        [Test]
        public void CreateTestPackage_returns_empty_package_if_no_test_assemblies_found()
        {
            ICompiler compiler = GetCompiler();

            var testPackageService = new TestPackageService(GetTextRetriever(), compiler, new DirectoryUri(OutputDirectory));

            ITestPackage testPackage = testPackageService.CreateTestPackage(solutionFile);

            Assert.That(testPackage, Is.Not.Null);
            Assert.That(testPackage.Assemblies.Count, Is.EqualTo(0));
        }

        [Test]
        public void CreateTestPackage_compiles_all_projects_in_solution()
        {
            ICompiler compiler = GetCompiler();

            var testPackageService = new TestPackageService(GetTextRetriever(), compiler, new DirectoryUri(OutputDirectory));

            testPackageService.CreateTestPackage(solutionFile);

            compiler.AssertWasCalled(c => c.Compile(null), settings => settings.IgnoreArguments());
        }

        private ICompiler GetCompiler()
        {
            var compiler = MockRepository.GenerateStub<ICompiler>();
            compiler.Stub(c => c.Compile(null)).IgnoreArguments();
            return compiler;
        }

        private EmbeddedResourceTextRetriever GetTextRetriever()
        {
            var settings = new EmbeddedResourceTextRetrieverSettings(EmbeddedResourceTestSolutionPath);
            return new EmbeddedResourceTextRetriever(settings);
        }
    }
}